<?php
/**
 * 配置管理器
 * 用于动态管理应用配置项
 */
namespace core;

use core\cache\CacheManager;

class Config
{
    // 存储所有配置项
    private static $config = [];
    // 存储配置项变更的监听器
    private static $listeners = [];
    
    // 配置缓存键
    private static $cacheKey = 'config_cache';
    
    /**
     * 初始化配置
     * @param array $config 初始配置数组
     */
    public static function init($config = [])
    {
        // 尝试从缓存获取配置
        $cachedConfig = CacheManager::get(self::$cacheKey);
        
        if ($cachedConfig) {
            self::$config = $cachedConfig;
            Debug::log('配置已从缓存加载');
        } else {
            self::$config = $config;
            
            // 缓存配置
            CacheManager::set(self::$cacheKey, self::$config, 86400);
            Debug::log('配置已缓存');
        }
    }
    
    /**
     * 获取配置项
     * @param string $key 配置项键名，支持点表示法访问层级配置
     * @param mixed $default 默认值
     * @return mixed
     */
    public static function get($key = null, $default = null)
    {
        if ($key === null) {
            return self::$config;
        }

        // 处理层级配置
        $keys = explode('.', $key);
        $value = self::$config;

        foreach ($keys as $k) {
            if (!isset($value[$k])) {
                return $default;
            }
            $value = $value[$k];
        }

        return $value;
    }
    
    /**
     * 设置配置项
     * @param string $key 配置项键名
     * @param mixed $value 配置值
     */
    public static function set($key, $value)
    {
        // 清除配置缓存
        CacheManager::delete(self::$cacheKey);
        
        $keys = explode('.', $key);
        $config = &self::$config;

        foreach ($keys as $k) {
            if (!isset($config[$k])) {
                $config[$k] = [];
            }
            $config = &$config[$k];
        }

        $config = $value;
    }

    /**
     * 检查配置项是否存在
     * @param string $key 配置项键名
     * @return bool
     */
    public static function has($key) {
        return self::get($key) !== null;
    }

    /**
     * 注册配置变更监听器
     * @param string $key 配置项键名
     * @param callable $listener 监听器回调函数
     */
    public static function on($key, callable $listener) {
        if (!isset(self::$listeners[$key])) {
            self::$listeners[$key] = [];
        }
        self::$listeners[$key][] = $listener;
    }

    /**
     * 移除配置变更监听器
     * @param string $key 配置项键名
     * @param callable $listener 监听器回调函数（可选，为空则移除所有）
     */
    public static function off($key, callable $listener = null) {
        if (!isset(self::$listeners[$key])) {
            return;
        }

        if ($listener === null) {
            unset(self::$listeners[$key]);
        } else {
            $index = array_search($listener, self::$listeners[$key]);
            if ($index !== false) {
                unset(self::$listeners[$key][$index]);
            }
        }
    }

    /**
     * 通知配置变更监听器
     * @param string $key 配置项键名
     * @param mixed $oldValue 旧值
     * @param mixed $newValue 新值
     */
    private static function notifyListeners($key, $oldValue, $newValue) {
        // 通知精确匹配的监听器
        if (isset(self::$listeners[$key])) {
            foreach (self::$listeners[$key] as $listener) {
                call_user_func($listener, $oldValue, $newValue);
            }
        }

        // 通知通配符监听器
        $parts = explode('.', $key);
        while (array_pop($parts)) {
            $parentKey = implode('.', $parts);
            if ($parentKey && isset(self::$listeners[$parentKey . '.*'])) {
                foreach (self::$listeners[$parentKey . '.*'] as $listener) {
                    call_user_func($listener, $key, $oldValue, $newValue);
                }
            }
        }

        // 通知全局监听器
        if (isset(self::$listeners['*'])) {
            foreach (self::$listeners['*'] as $listener) {
                call_user_func($listener, $key, $oldValue, $newValue);
            }
        }
    }
    
    // 添加环境变量支持
    public static function loadEnv($file = '.env') {
        if (file_exists($file)) {
            $env = parse_ini_file($file, true);
            foreach ($env as $key => $value) {
                if (is_array($value)) {
                    foreach ($value as $k => $v) {
                        $_ENV[strtoupper($key).'_'.strtoupper($k)] = $v;
                    }
                } else {
                    $_ENV[strtoupper($key)] = $value;
                }
            }
        }
    }
    
    // 从环境变量获取配置
    public static function getFromEnv($key, $default = null) {
        $envKey = strtoupper(str_replace('.', '_', $key));
        return $_ENV[$envKey] ?? $default;
    }
}